﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Reflection;
using System.Data;
using Water.Architecture2.IDAL;
using Water.Util;
using System.Web.UI.WebControls;
using System.Web;
using System.Collections;

namespace Water.Web.Controls
{
    class ObjectHierarchyData : IHierarchyData
    {
        #region private field

        private object typeInstance;
        private MethodInfo method;
        private string parentPath;
        private DataRowView item;
        private string dataIDField;
        private string dataParentIDField;
        private string isLeafField;
        private DataSet childItems ;
        private ParameterCollection _selectParameters;
        private ParameterCollection _rootParameters;

        private HttpContext _context;
        private ObjectHierarchicalDataSource _owner;

        #endregion

        #region Constructors
        public ObjectHierarchyData(string dataIDField, string dataParentIDField, string isLeafField, string parentPath, DataRowView item, object typeInstance, MethodInfo method, HttpContext context, ObjectHierarchicalDataSource owner, ParameterCollection selectParameters, ParameterCollection rootParameters)
        {
            this.parentPath = parentPath;
            this.item = item;
            this.typeInstance = typeInstance;
            this.method = method;
            this.dataIDField = dataIDField;
            this.dataParentIDField = dataParentIDField;
            this.isLeafField = isLeafField;

            this._context = context;
            this._owner = owner;
            this._selectParameters = selectParameters;
            this._rootParameters = rootParameters;
        }
        #endregion

        #region IHierarchyData 成员

        public IHierarchicalEnumerable GetChildren()
        {
            if (string.IsNullOrEmpty(this.isLeafField))
            {
                return GetChildrenHelp();
            }
            else
            {
                if (this.HasChildren)
                {
                    return GetChildrenHelp();
                }
                else
                    return null;
            }
        }

        public IHierarchyData GetParent()
        {
            int _index = this.parentPath.LastIndexOf('/');
            if (_index > -1)
            {
                string _parentParentPath = this.parentPath.Substring(0, _index);

                WhereFields wheres = new WhereFields();
                wheres.Add(this.dataIDField, OperatorType.Equals, this.item[this.dataParentIDField]);
                ProcessSelectParameters(wheres);
                WhereFields[] parameters = new WhereFields[] { wheres };
                DataSet _parentItem = (DataSet)method.Invoke(this.typeInstance, parameters);
                if (_parentItem.Tables[0].DefaultView.Count>0)
                    return new ObjectHierarchyData(this.dataIDField, this.dataParentIDField,isLeafField, _parentParentPath, _parentItem.Tables[0].DefaultView[0], typeInstance, method,_context,_owner,_selectParameters,_rootParameters);
                else
                    return null;
            }
            return null;
        }

        public bool HasChildren
        {
            get
            {
                if (string.IsNullOrEmpty(this.isLeafField))
                {
                    EnsureGetChildren();
                    return childItems.Tables[0].DefaultView.Count > 0 ? true : false;
                }
                else
                {
                    string _strIsLeafField = this.item[this.isLeafField].ToString();
                    bool ret = false;
                    ret=ret.ParseDB(_strIsLeafField);
                    return !ret;
                }
            }
        }

        public object Item
        {
            get { return this.item; }
        }

        public string Path
        {
            get { return string.Format("{0}/{1}", parentPath, item[this.dataIDField]); }
        }

        public string Type
        {
            get { return item.GetType().ToString(); }
        }

        #endregion


        #region help method

        private IHierarchicalEnumerable GetChildrenHelp()
        {
            EnsureGetChildren();

            if (childItems.Tables[0].DefaultView.Count > 0)
                return new ObjectHierarchicalDataCollection(dataIDField, dataParentIDField, isLeafField, parentPath, childItems, typeInstance, method, _context, _owner, _selectParameters, _rootParameters);
            else
                return null;
        }

        private void EnsureGetChildren()
        {
            if (childItems == null)
            {
                WhereFields wheres = new WhereFields();
                wheres.Add(this.dataParentIDField, OperatorType.Equals, this.item[this.dataIDField]);
                ProcessSelectParameters(wheres);
                WhereFields[] parameters = new WhereFields[] { wheres };
                childItems = (DataSet)method.Invoke(this.typeInstance, parameters);
            }
        }

        private void ProcessRootParameters(WhereFields wheres)
        {
            foreach (DictionaryEntry entry in this._rootParameters.GetValues(this._context, this._owner))
            {
                wheres.Add(entry.Key.ToString(), OperatorType.Equals, entry.Value);
            }
        }
        private void ProcessSelectParameters(WhereFields wheres)
        {
            foreach (DictionaryEntry entry in this._selectParameters.GetValues(this._context, this._owner))
            {
                wheres.Add(entry.Key.ToString(), OperatorType.Equals, entry.Value);
            }
        }

        #endregion
    }
}
